package com.sigmatrix.h5.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.sigmatrix.h5.dao.CodeCirculationDao;
import com.sigmatrix.h5.dao.OutStorageDao;
import com.sigmatrix.h5.dto.DisDealersData;
import com.sigmatrix.h5.dto.DisTerminalShopData;
import com.sigmatrix.h5.dto.EnterpriseData;
import com.sigmatrix.h5.dto.ProductData;
import com.sigmatrix.h5.dto.WarehouseData;
import com.sigmatrix.h5.entity.CodeCirculation;
import com.sigmatrix.h5.entity.FirstLevelQRCode;
import com.sigmatrix.h5.entity.MultistageLevelQRCode;
import com.sigmatrix.h5.entity.OutStorage;
import com.sigmatrix.h5.enums.CodeCirculationStatus;
import com.sigmatrix.h5.enums.MultistageLevelQRCodeStatusEnum;
import com.sigmatrix.h5.exception.DaoException;
import com.sigmatrix.h5.exception.ServiceException;
import com.sigmatrix.h5.service.CodeCirculationService;
import com.sigmatrix.h5.service.DealerService;
import com.sigmatrix.h5.service.DisTerminalShopService;
import com.sigmatrix.h5.service.EnterpriseService;
import com.sigmatrix.h5.service.ProductService;
import com.sigmatrix.h5.service.WarehouseService;
import com.sigmatrix.h5.utils.Cons;
import com.sigmatrix.h5.utils.QRCodeUtil;
import com.sigmatrix.h5.utils.Utils;
import com.sigmatrix.h5.web.vo.InStorageVo;
import com.sigmatrix.h5.web.vo.OutStorageVo;

/**
 * 
 *@ClassName: CodeCirculationServiceImpl
 *@Description: 码流转记录
 *@author MH
 *@date 2017年11月30日 上午10:13:39
 */
@Service
public class CodeCirculationServiceImpl implements CodeCirculationService{
	
	/**码流转记录mongo db操作接口*/
	@Autowired
	private transient CodeCirculationDao codeCirculationDao;
	
	/**仓库业务层接口*/
	@Autowired
	private transient WarehouseService warehouseService;
	
	/**企业业务层接口*/
	@Autowired
	private transient EnterpriseService enterpriseService;
	
	/**产品业务层接口*/
	@Autowired
	private transient ProductService productService;
	
	/**出库单数据库操作接口*/
	@Autowired
	private transient OutStorageDao outStorageDao;
	
	/**经销商信息业务层接口*/
	@Autowired
	private transient DealerService dealersService;
	
	/**终端店信息业务层接口*/
	@Autowired
	private transient DisTerminalShopService disTerminalShopService;
	
	@Autowired
	protected transient MongoTemplate mongoTemplate;
	
	
	/**组织类型:1-企业*/
	public static final int ORGANIZATION_TYPE_ENT = 1;
	
	/**组织类型:2-经销商*/
	public static final int ORGANIZATION_TYPE_DEALER = 2;
	
	/**组织类型:3-终端店*/
	public static final int ORGANIZATION_TYPE_STORE = 3;
	
	/** 码状态：1入库2销售出库3返工出库4调拨出库5其他出库  */
	public static final int SALE_OUT_STORAGE=2;
	
	@Override
	public List<CodeCirculation> select(CodeCirculation t) {
		return select(t,null);
	}

	@Override
	public List<CodeCirculation> select(CodeCirculation t, Map<String, String> order) {
		
		return codeCirculationDao.select(t, order);
	}
	
	@Override
	public List<CodeCirculation> select(CodeCirculation t, Map<String, String> order,String eseCode) {
		String tableName = codeCirculationDao.getTableName(eseCode);
		return codeCirculationDao.select(t, order,tableName);
	}


	@Override
	public CodeCirculation selectOne(CodeCirculation t) {
		return selectOne(t, null);
	}

	@Override
	public CodeCirculation selectOne(CodeCirculation t, Map<String, String> order) {
		return codeCirculationDao.selectOne(t, order);
	}

	@Override
	public void insert(CodeCirculation t) {
		codeCirculationDao.insert(t);
		
	}

	@Override
	public CodeCirculation findByQrCode(String qrCode) {
		CodeCirculation code = new CodeCirculation();
		code.setQrCode(qrCode);
		Map<String,String> order = new HashMap<String,String>();
		order.put("createTime", "desc");
		return selectOne(code, order);
	}
	
	
	/**(non-Javadoc)
	 *@Title: saveOutStorageCodeCirculation
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.service.CodeCirculationService#saveOutStorageCodeCirculation(com.sigmatrix.sc.handheld.inter.web.vo.OutStorageVo, java.util.Map)
	 *@author youjun
	 *@date 2017年8月13日 下午5:50:11
	 */
	@Override
	public void saveOutStorageCodeCirculation(final OutStorageVo outStorageVo, final Map<String, Object> map) throws ServiceException {

		if(outStorageVo==null || CollectionUtils.isEmpty(map)
				||StringUtils.isBlank(outStorageVo.getEnterpriseCode())
				||outStorageVo.getWarehouseId()==null
				||outStorageVo.getChannelType()==null) {
			throw new ServiceException("记录出库码流转记录参数错误");
		}
		
		final String enterpriseCode = outStorageVo.getEnterpriseCode();
		final EnterpriseData enterprise = enterpriseService.findByEnterpriseCode(enterpriseCode);
		final Short channelType = outStorageVo.getChannelType(); // 出库类型
		if(enterprise==null){
			throw new ServiceException("企业不存在");
		}
		//获取工单
		OutStorage outStorageData = null;
		try {
			outStorageData = outStorageDao.findById(outStorageVo.getOutStorageId(), enterpriseCode);
		} catch (DaoException e) {
			e.printStackTrace();
		}
		final Integer sendDealerId = outStorageData.getSendDealerId();
		final Integer warehouseId = outStorageData.getWarehouseId();
		DisDealersData dealear = null;
		WarehouseData warehouse = null;
		//发货经销商
		if (Utils.isNotEmptyZero(sendDealerId)) {
			dealear = dealersService.findById(sendDealerId, enterpriseCode);
			//发货仓库
			if (Utils.isNotEmptyZero(warehouseId)) {
				warehouse = warehouseService.findById(warehouseId, enterpriseCode);
			}	
		}
		
		final Integer delegatedDealerId = outStorageData.getTargetChannelId();
		final Integer toWarehouseId = outStorageData.getToWarehouseId();
		final Integer dealerId = outStorageData.getDealerId();
		DisDealersData delegatedDealer = null;
		WarehouseData toWarehouse = null;
		DisTerminalShopData disTerminalShopData = null;
		if (Utils.isNotEmptyZero(delegatedDealerId)) {
			delegatedDealer = dealersService.findById(delegatedDealerId, enterpriseCode);
			if (Utils.isNotEmptyZero(toWarehouseId)) {
				toWarehouse = warehouseService.findById(toWarehouseId, enterpriseCode);
			}
		}
		else {
			if (Utils.isNotEmptyZero(dealerId)) {
				if (outStorageData.getCustomerType() == Cons.TAG_LEVEL_DEALER) {
					delegatedDealer = dealersService.findById(dealerId, enterpriseCode);
				}
				else {
					disTerminalShopData = disTerminalShopService.findById(dealerId, enterpriseCode);
				}
				
			}
			if (Utils.isNotEmptyZero(toWarehouseId)) {
				toWarehouse = warehouseService.findById(toWarehouseId, enterpriseCode);
			}
		}
		
		// 企业码流转记录表名为:企业code+CodeCirculation
		final String entCodeCirculationName = enterpriseCode + Cons.BASIC_CODECIRCULATION_DOCUMENT_NAME;
		@SuppressWarnings("unchecked")
		final List<MultistageLevelQRCode> outPackLevelCodeList = (List<MultistageLevelQRCode>) map.get("outPackLevelCodeList");
		@SuppressWarnings("unchecked")
		final List<FirstLevelQRCode> outSingleLevelCodeList = (List<FirstLevelQRCode>) map.get("outSingleLevelCodeList");
		

		final Map<Integer, ProductData> productMap = new HashMap<Integer, ProductData>();
		final List<CodeCirculation> list = new ArrayList<CodeCirculation>();
		if(!CollectionUtils.isEmpty(outPackLevelCodeList)) {
			for(final MultistageLevelQRCode item:outPackLevelCodeList) {
				
				final CodeCirculation codeCirculation = new CodeCirculation();
				codeCirculation.setCreateTime(new Date());
				codeCirculation.setLevel(item.getPackLevel());
				if (Utils.isNotEmpty(warehouse)) {
					codeCirculation.setFromWarehouseCode(warehouse.getWarehouseCode());//发货经销商仓库
					codeCirculation.setFromWarehouseName(warehouse.getWarehouseName());//发货经销商名称
				}
				if (Utils.isNotEmpty(toWarehouse)) {
					codeCirculation.setToWarehouseCode(toWarehouse.getWarehouseCode());//收货经销商仓库
					codeCirculation.setToWarehouseName(toWarehouse.getWarehouseName());//收货经销商名称
				}
				if (Utils.isNotEmpty(dealear)) {
					codeCirculation.setOrganizationType(ORGANIZATION_TYPE_DEALER);
					codeCirculation.setOrganizationCode(dealear.getDealerCode());//发货经销商code
					codeCirculation.setOrganizationName(dealear.getDealerName());//发货经销商名称
				}
				if (outStorageData.getCustomerType() == Cons.TAG_LEVEL_DEALER) {
					if (Utils.isNotEmpty(delegatedDealer)) {
						codeCirculation.setDealersType(ORGANIZATION_TYPE_DEALER);
						codeCirculation.setDealersCode(delegatedDealer.getDealerCode());//收货经销商code
						codeCirculation.setDealersName(delegatedDealer.getDealerName());//收货经销商名称
					}
					
				}
				else {
					if (Utils.isNotEmpty(disTerminalShopData)) {
						codeCirculation.setDealersType(ORGANIZATION_TYPE_STORE);
						codeCirculation.setDealersCode(disTerminalShopData.getCode());//门店code
						codeCirculation.setDealersName(disTerminalShopData.getName());//门店名称	
					}
					
				}
	
				codeCirculation.setProductBatchCode(item.getBatchCode());
				// 填充产品信息
				fillProductInfo(enterpriseCode, productMap, item.getProductId(), codeCirculation);
				codeCirculation.setQrCode(item.getPackContent());
				codeCirculation.setStatus(QRCodeUtil.getOutStorageCodeStatus(channelType));
				codeCirculation.setUrlDomain(item.getCodeUrl());
				if (Utils.isNotEmpty(outStorageData)) {
					codeCirculation.setWorkOrderId(outStorageData.getOrderCode());//工单号
				}
				list.add(codeCirculation);
			}
			
		}
		if(!CollectionUtils.isEmpty(outSingleLevelCodeList)) {
			for(final FirstLevelQRCode item:outSingleLevelCodeList) {
				
				final CodeCirculation codeCirculation = new CodeCirculation();
				codeCirculation.setCreateTime(new Date());
				codeCirculation.setLevel(1);
				if (Utils.isNotEmpty(warehouse)) {
					codeCirculation.setFromWarehouseCode(warehouse.getWarehouseCode());//发货经销商仓库
					codeCirculation.setFromWarehouseName(warehouse.getWarehouseName());//发货经销商名称
				}
				if (Utils.isNotEmpty(toWarehouse)) {
					codeCirculation.setToWarehouseCode(toWarehouse.getWarehouseCode());//收货经销商仓库
					codeCirculation.setToWarehouseName(toWarehouse.getWarehouseName());//收货经销商名称
				}
				if (Utils.isNotEmpty(dealear)) {
					codeCirculation.setOrganizationType(ORGANIZATION_TYPE_DEALER);
					codeCirculation.setOrganizationCode(dealear.getDealerCode());//发货经销商code
					codeCirculation.setOrganizationName(dealear.getDealerName());//发货经销商名称
				}
				if (Utils.isNotEmpty(delegatedDealer)) {
					codeCirculation.setDealersCode(delegatedDealer.getDealerCode());//收货经销商code
					codeCirculation.setDealersName(delegatedDealer.getDealerName());//收货经销商名称
				}
				codeCirculation.setProductBatchCode(item.getBatchCode());
				// 填充产品信息
				fillProductInfo(enterpriseCode, productMap, item.getProductId(), codeCirculation);
				codeCirculation.setQrCode(item.getQrCode());
				codeCirculation.setStatus(QRCodeUtil.getOutStorageCodeStatus(channelType));
				codeCirculation.setUrlDomain(item.getCodeUrl());
				if (Utils.isNotEmpty(outStorageData)) {
					codeCirculation.setWorkOrderId(outStorageData.getOrderCode());//工单号
				}
				list.add(codeCirculation);
			}
			
		}
		if(!CollectionUtils.isEmpty(list)) {
			//codeCirculationDao.batchSave(list, entCodeCirculationName);
			mongoTemplate.insert(list, entCodeCirculationName);
			
		}
		
	}

	/**(non-Javadoc)
	 *@Title: saveInStorageCodeCirculation
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.service.CodeCirculationService#saveInStorageCodeCirculation(com.sigmatrix.sc.handheld.inter.web.vo.InStorageVo, java.util.Map)
	 *@author youjun
	 *@date 2017年8月22日 下午2:34:56
	 */
	@SuppressWarnings("unused")
	@Override
	public void saveInStorageCodeCirculation(InStorageVo inStorageVo, Map<String, Object> map)
			throws ServiceException {
		
		if(inStorageVo==null || CollectionUtils.isEmpty(map)
				||StringUtils.isBlank(inStorageVo.getEnterpriseCode())
				||inStorageVo.getWarehouseId()==null
				||inStorageVo.getChannelType()==null) {
			throw new ServiceException("记录入库码流转记录参数错误");
		}
		final String enterpriseCode = inStorageVo.getEnterpriseCode();
		final EnterpriseData enterprise = enterpriseService.findByEnterpriseCode(enterpriseCode);
		final Short channelType = inStorageVo.getChannelType(); // 入库类型
		if(enterprise==null){
			throw new ServiceException("企业不存在");
		}
		// 企业码流转记录表名为:企业code+CodeCirculation
		final String entCodeCirculationName = enterpriseCode + Cons.BASIC_CODECIRCULATION_DOCUMENT_NAME;
		@SuppressWarnings("unchecked")
		final List<MultistageLevelQRCode> inPackLevelCodeList = (List<MultistageLevelQRCode>) map.get("inPackLevelCodeList");
		@SuppressWarnings("unchecked")
		final List<FirstLevelQRCode> inSingleLevelCodeList = (List<FirstLevelQRCode>) map.get("inSingleLevelCodeList");
		final Integer warehouseId = inStorageVo.getWarehouseId();
		final WarehouseData warehouse = warehouseService.findById(warehouseId, enterpriseCode);
		if(warehouse==null){
			throw new ServiceException("仓库不存在");
		}
		final List<CodeCirculation> list = new ArrayList<CodeCirculation>();
		final Map<Integer, ProductData> productMap = new HashMap<Integer, ProductData>();
		if(!CollectionUtils.isEmpty(inPackLevelCodeList)) {
			for(final MultistageLevelQRCode item:inPackLevelCodeList) {
				
				final CodeCirculation codeCirculation = new CodeCirculation();
				codeCirculation.setCreateTime(new Date());
				codeCirculation.setFromWarehouseCode(warehouse.getWarehouseCode());
				codeCirculation.setFromWarehouseName(warehouse.getWarehouseName());
				codeCirculation.setLevel(item.getPackLevel());
				codeCirculation.setOrganizationType(ORGANIZATION_TYPE_ENT);
				codeCirculation.setOrganizationCode(enterpriseCode);
				codeCirculation.setOrganizationName(enterprise.getName());
				codeCirculation.setProductBatchCode(item.getBatchCode());
				// 填充产品信息
				fillProductInfo(enterpriseCode, productMap, item.getProductId(), codeCirculation);
				codeCirculation.setQrCode(item.getPackContent());
				codeCirculation.setStatus(MultistageLevelQRCodeStatusEnum.IN_STORAGE.getId());
				codeCirculation.setUrlDomain(item.getCodeUrl());
				codeCirculation.setWorkOrderId(inStorageVo.getWorkId());
//				codeCirculationDao.save(codeCirculation);
				list.add(codeCirculation);
			}
			
		}
		if(!CollectionUtils.isEmpty(inSingleLevelCodeList)) {
			for(final FirstLevelQRCode item:inSingleLevelCodeList) {
				
				final CodeCirculation codeCirculation = new CodeCirculation();
				codeCirculation.setCreateTime(new Date());
				codeCirculation.setFromWarehouseCode(warehouse.getWarehouseCode());
				codeCirculation.setFromWarehouseName(warehouse.getWarehouseName());
				codeCirculation.setLevel(1);
				codeCirculation.setOrganizationType(ORGANIZATION_TYPE_ENT);
				codeCirculation.setOrganizationCode(enterpriseCode);
				codeCirculation.setOrganizationName(enterprise.getName());
				codeCirculation.setProductBatchCode(item.getBatchCode());
				// 填充产品信息
				fillProductInfo(enterpriseCode, productMap, item.getProductId(), codeCirculation);
				codeCirculation.setQrCode(item.getQrCode());
				codeCirculation.setStatus(MultistageLevelQRCodeStatusEnum.IN_STORAGE.getId());
				codeCirculation.setUrlDomain(item.getCodeUrl());
				codeCirculation.setWorkOrderId(inStorageVo.getWorkId());
//				codeCirculationDao.save(codeCirculation);
				list.add(codeCirculation);
			}
			
		}
		if(!CollectionUtils.isEmpty(list)) {
			//codeCirculationDao.batchSave(list, entCodeCirculationName);
			mongoTemplate.insert(list, entCodeCirculationName);
		}
	}

	/**
	 *@Title: fillProductInfo
	 *@Description: TODO()
	 *@return void
	 *@author youjun
	 *@date 2017年8月27日 下午10:47:27
	 *@param enterpriseCode
	 *@param productMap
	 *@param item
	 *@param codeCirculation
	 *@throws ServiceException
	 */
	private void fillProductInfo(final String enterpriseCode, final Map<Integer, ProductData> productMap,
			final Integer productId, final CodeCirculation codeCirculation) throws ServiceException {
		String productCode = "";
		String productName = "";
		if(productId!=null) {
			ProductData product = null;
			if(productMap.containsKey(productId)) {
				product = productMap.get(productId);
			}else{
				product = productService.findById(productId, false, enterpriseCode);
				productMap.put(productId, product); // 放入map
			}
			productCode = product!=null?product.getProductCode():"";
			productName = product!=null?product.getProductName():"";
		}
		codeCirculation.setProductCode(productCode);
		codeCirculation.setProductName(productName);
	}

	/**(non-Javadoc)
	 * 
	 * 根据qrCode查询 销售出库的 码流转信息
	 * 
	 *@see com.sigmatrix.h5.service.CodeCirculationService#findListByQrCode(java.lang.String)
	 *@author wjwei
	 *@date 2018年3月21日 下午3:20:24
	 */
	@Override
	public List<CodeCirculation> findListByQrCode(String qrCode) {
		CodeCirculation code = new CodeCirculation();
		code.setQrCode(qrCode);
		code.setStatus(SALE_OUT_STORAGE);
		Map<String,String> order = new HashMap<String,String>();
		order.put("createTime", "desc");
		return select(code, order);
	}
	
	@Override
	public List<CodeCirculation> findListByQrCode(String qrCode,String eseCode) {
		CodeCirculation code = new CodeCirculation();
		code.setQrCode(qrCode);
		code.setStatus(SALE_OUT_STORAGE);
		Map<String,String> order = new HashMap<String,String>();
		order.put("createTime", "desc");
		
		return setDefault(select(code, order,eseCode));
	}
	
	@Override
	public List<CodeCirculation> findListByQrCode(String qrCode,String eseCode,CodeCirculationStatus status) {
		CodeCirculation code = new CodeCirculation();
		code.setQrCode(qrCode);
		if(status != null){			
			code.setStatus(status.value);
		}
		Map<String,String> order = new HashMap<String,String>();
		order.put("createTime", "desc");
		
		return setDefault(select(code, order,eseCode));
	}
	
	private List<CodeCirculation> setDefault(List<CodeCirculation> circulations) {
		if(circulations==null){
			return circulations;				
		}
		for (CodeCirculation codeCirculation : circulations) {
			if(codeCirculation.getDealersType()==null){
				codeCirculation.setDealersType(2);
			}
		}
		return circulations;						
	}

}
